#include <gtest/gtest.h>
#include <vector>
#include "geometry.h"

int main( int argc, char ** argv ) {
    ::testing::InitGoogleTest( &argc, argv );

    return RUN_ALL_TESTS();
}

TEST( EdgeTest, RelativePosition ) {
    Point p1( 1, 1 ), p2( 3, 3 );
    std::vector<std::pair<Point, Edge::Position>> pp;
    pp.emplace_back( Point( -1, -1 ), Edge::Position::BACK );
    pp.emplace_back( Point( 5, 5 ), Edge::Position::FRONT );
    pp.emplace_back( Point( 2, 2 ), Edge::Position::BELONG );
    pp.emplace_back( Point( 0, 5 ), Edge::Position::LEFT );
    pp.emplace_back( Point( 5, 0 ), Edge::Position::RIGHT );

    Point behind( -1, -1 ), infront( 5, 5 ), right( 10, 0 ), left( 0, 10 ), belong( 2, 2 );

    Edge e( p1, p2 );

    for ( auto p : pp )
    { ASSERT_EQ( e.relPos( p.first ), p.second ); }
}

TEST( EdgeTest, PolarAngle ) {
    auto checkAngle = []( const Point & from, const Point & to, double value ) { ASSERT_DOUBLE_EQ( Edge::polarAngle( from, to ), value ); };
    Point from( 5, 5 );
    checkAngle( from, Point( 6, 5 ), 0 );
    checkAngle( from, Point( 6, 6 ), 45 );
    checkAngle( from, Point( 5, 6 ), 90 );
    checkAngle( from, Point( 4, 6 ), 135 );
    checkAngle( from, Point( 4, 5 ), 180 );
    checkAngle( from, Point( 4, 4 ), 225 );
    checkAngle( from, Point( 5, 4 ), 270 );
    checkAngle( from, Point( 6, 4 ), 315 );
}

TEST( EdgeTest, isCrossing ) {
    auto e = []( int a, int b, int c, int d ) { return Edge( Point( a, b ), Point( c, d ) ); };
    ASSERT_FALSE( e( 1, 1, 5, 1 ).isCrossing( e( 1, 2, 5, 2 ) ) );
    ASSERT_FALSE( e( 1, 2, 1, 1 ).isCrossing( e( 2, 1, 5, 1 ) ) );

    ASSERT_TRUE( e( 1, 1, 5, 1 ).isCrossing( e( 4, 1, 1, 1 ) ) );
    ASSERT_TRUE( e( 1, 1, 2, 2 ).isCrossing( e( 1, 2, 2, 1 ) ) );
    ASSERT_TRUE( e( 1, 1, 3, 3 ).isCrossing( e( 2, 2, 3, 1 ) ) );
    ASSERT_TRUE( e( 1, 1, 3, 3 ).isCrossing( e( 1, 3, 3, 1 ) ) );
    ASSERT_TRUE( e( 1, 1, 3, 3 ).isCrossing( e( 3, 3, 5, 5 ) ) );
    ASSERT_TRUE( e( 1, 1, 3, 3 ).isCrossing( e( 3, 3, 1, 1 ) ) );
}
